package vip.xiaonuo.megvii.service;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.HttpClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.digest.DigestHttpClient;
import vip.xiaonuo.digest.DigestHttpUtil;
import vip.xiaonuo.facedoor.modular.device.service.DeviceService;
import vip.xiaonuo.facedoor.modular.memberfeatures.entity.MemberFeatures;
import vip.xiaonuo.facedoor.modular.memberfeatures.service.MemberFeaturesService;
import vip.xiaonuo.megvii.BaseConfig;
import vip.xiaonuo.megvii.config.model.ApiResponse;
import vip.xiaonuo.megvii.facegroups.FaceGroupCodeDefinition;
import vip.xiaonuo.megvii.facegroups.model.FaceGroupBind;
import vip.xiaonuo.modular.devicemegvii.entity.DeviceMegvii;
import vip.xiaonuo.modular.devicemegvii.service.DeviceMegviiService;
import vip.xiaonuo.modular.facegroupfacetokenrela.entity.FacegroupFacetokenRela;
import vip.xiaonuo.modular.facegroupfacetokenrela.param.FaceGroupFaceTokenRelaSave;
import vip.xiaonuo.modular.facegroupfacetokenrela.param.FacegroupFacetokenRelaParam;
import vip.xiaonuo.modular.facegroupfacetokenrela.service.FacegroupFacetokenRelaService;
import vip.xiaonuo.modular.megviifacegroup.entity.MegviiFaceGroup;
import vip.xiaonuo.modular.megviifacegroup.service.MegviiFaceGroupService;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class DeviceMegviiFaceGroupFaceTokenRelaService extends DeviceMegviiBaseService{

    @Resource
    private DeviceMegviiService deviceMegviiService;

    @Resource
    private MemberFeaturesService memberFeaturesService;

    @Resource
    private FacegroupFacetokenRelaService relaService;

    @Resource
    private MegviiFaceGroupService faceGroupService;

    /**
     * 保存人脸分组关联
     * @param param
     * @return
     */
    @Transactional( rollbackFor = {Exception.class} )
    public ApiResponse saveFaceGroupRelation(FaceGroupFaceTokenRelaSave param) {

        List<Long> adds = param.getAddRelate();
        List<Long> deletes = param.getRemoveRelate();
        if( (adds==null || adds.size()==0 ) && (deletes==null || deletes.size()==0)){
            return new ApiResponse(0,"本次未修改任何数据,无需处理",null,null,null);
        }
        // 获取设备，然后获取请求HttpClient
        MemberFeatures feature = memberFeaturesService.getById(param.getFeaturesId());
        DeviceMegvii device = deviceMegviiService.getById(feature.getBizDeviceId());
        HttpClient client = DigestHttpClient.getDigestHttpClient(device);
        // 先查出所有的本地关联信息
        FacegroupFacetokenRelaParam relationParam = new FacegroupFacetokenRelaParam();
        relationParam.setFeaturesId(param.getFeaturesId());
        List<FacegroupFacetokenRela> relations = relaService.list(relationParam);
        Map<Long,FacegroupFacetokenRela> relationMap = new HashMap<>();
        for (FacegroupFacetokenRela relation : relations) {
            relationMap.put(relation.getFaceGroupId(), relation);
        }

        ApiResponse finalResp ;
        String result = "";
        if(adds !=null && adds.size()>0){
            ApiResponse resp = this.doAddRelation(client,device,feature,adds,relationMap);
            if(resp.getCode()!=0 ){
                result += "绑定失败，原因：" +  FaceGroupCodeDefinition.getMessage(resp.getCode());;
            }
        }

        if(deletes !=null && deletes.size()>0){
            ApiResponse resp = this.doDeleteRelation(client,device,feature,deletes,relationMap);
            if(resp.getCode()!=0 ){
                result += "解绑失败，原因：" +  FaceGroupCodeDefinition.getMessage(resp.getCode());;
            }
        }
        if(result.equals("")){
            return ApiResponse.success();
        }else{
            return ApiResponse.failed(-1,result);
        }
    }


    protected ApiResponse doAddRelation(HttpClient client,DeviceMegvii device,MemberFeatures feature, List<Long> adds,Map<Long,FacegroupFacetokenRela> relationMap){
        String faceToken = feature.getFaceToken();
        String url = getMachAddress(device) + BaseConfig.URL_FACE_GROUP_BIND.replace("{faceToken}",faceToken);

        List<MegviiFaceGroup> groups = faceGroupService.listByIds(adds);

        String[] arr = new String[groups.size()];
        for(int i = 0 ; i < groups.size() ; i++){
            arr[i] = groups.get(i).getGroupName();
        }
        FaceGroupBind bindData = new FaceGroupBind();
        bindData.setFaceGroupList(arr);
        ApiResponse resp = DigestHttpUtil.sendPost(client,url, JSON.toJSONString(bindData));
        if(resp.getCode()==0){
            // 重复绑定也会进入该判断
            for(Long id : adds){
                if(!relationMap.containsKey(id)){
                    FacegroupFacetokenRela rela = new FacegroupFacetokenRela();
                    rela.setFaceGroupId(id);
                    rela.setFeaturesId(feature.getId());
                    relaService.save(rela);
                }
            }

            return ApiResponse.success();
        }else{
            return ApiResponse.failed(resp.getCode(),resp.getMessage());
        }
    }

    protected ApiResponse doDeleteRelation(HttpClient client, DeviceMegvii device,MemberFeatures feature, List<Long> deletes,Map<Long,FacegroupFacetokenRela> relationMap) {
        String faceToken = feature.getFaceToken();
        String url = getMachAddress(device) + BaseConfig.URL_FACE_GROUP_UNBIND.replace("{faceToken}",faceToken);

        List<MegviiFaceGroup> groups = faceGroupService.listByIds(deletes);

        String[] arr = new String[groups.size()];
        for(int i = 0 ; i < groups.size() ; i++){
            arr[i] = groups.get(i).getGroupName();
        }
        FaceGroupBind bindData = new FaceGroupBind();
        bindData.setFaceGroupList(arr);

        ApiResponse resp = DigestHttpUtil.sendDelete(client,url, JSON.toJSONString(bindData));
        if(resp.getCode()==0){
            for(Long id : deletes){
                if(relationMap.containsKey(id)){
                    FacegroupFacetokenRela rela = relationMap.get(id);
                    rela.setDelFlag(1);
                    relaService.saveOrUpdate(rela);
                }
            }
            return ApiResponse.success();
        }else{
            return ApiResponse.failed(resp.getCode(),resp.getMessage());
        }
    }

}
